<script setup>
import {onMounted, ref, reactive} from "vue";
import GlobalValue from "./utils/GlobalValue.js";
import GISUtil from "@/utils/GISUtil.js";
import Cell from "@/entity/Cell.js";
import DexieWrap from "@/utils/Dexie.js";

let rowNum = 20
let colNum = 10

let lastCellClick;
let lastCellDblClick;

let rowContainerStyleObj = reactive({
  height: (GlobalValue.rowHeight * rowNum) + 'px',
  width: GlobalValue.colWidth + 'px',
  backgroundColor: '#eeeeee',
})


let blankStyleObj = reactive({
  height: GlobalValue.rowHeight + 'px',
  width: GlobalValue.colWidth + 'px',
  backgroundColor: '#eeeeee',
})


let colContainerStyleObj = reactive({
  height: GlobalValue.rowHeight + 'px',
  width: (GlobalValue.colWidth * colNum) + 'px',
  backgroundColor: '#eeeeee',
})


// let data = [
//   {name: '1', age: '1'},
//   {name: '1', age: '2'},
// ]

function numberToExcelColumn(num) {
  let columnName = '';

  while (num > 0) {
    const remainder = (num - 1) % 26;
    columnName = String.fromCharCode(65 + remainder) + columnName;
    num = Math.floor((num - 1) / 26);
  }

  return columnName;
}

// 获取行列
function getRowCol(id) {
  var split = id.split('_');
  return {row: split[1], col: split[2]};
}

// 查询cellInfo
function queryCell(row, col) {
  return GlobalValue.cellList.find(cell => cell.row === Number(row) && cell.col === Number(col));
}

function queryCellByDom(dom) {
  let rowCol = getRowCol(dom.id);
  return queryCell(rowCol.row, rowCol.col);
}

// 添加选中
function addSelection(e, rect, divSelection, divSelectionInfo) {
  const offsetX = e.clientX - rect.left; // 视口坐标转元素相对坐标
  const offsetY = e.clientY - rect.top;
  // 创建一个新的 div 元素
  divSelection = $('<div>', {
    id: 'divSelection', // 设置 id
    class: 'divSelection', // 设置 class
    css: { // 设置 CSS 样式
      'left': offsetX + 'px',
      'top': offsetY + 'px',
    },
    text: '' // 设置文本内容
  });

  divSelectionInfo = {
    startX: offsetX
    , startY: offsetY
    , left: offsetX
    , right: offsetX
    , top: offsetY
    , bottom: offsetY
  }

  // 将新创建的 div 添加到 body 中
  $('#content').append(divSelection);
  return {divSelection, divSelectionInfo};
}


// 删除选中
function clearSelection(divSelection) {
  if (divSelection) {
    divSelection.css('width', 0)
    divSelection.css('height', 0)
    divSelection.remove();
  }

  if (GlobalValue.rowCellListSelected) {
    $(GlobalValue.rowCellListSelected.dom).css("border", GlobalValue.borderUnSelectionStyle)
  }
  if (GlobalValue.colCellListSelected) {
    $(GlobalValue.colCellListSelected.dom).css("border", GlobalValue.borderUnSelectionStyle)
  }

  GlobalValue.cellListSelected.forEach((cell) => {
    $(cell.dom).css("border", GlobalValue.borderUnSelectionStyle)
  })
  GlobalValue.cellListSelected = []
}


/**
 * 添加选中事件
 * @param cb
 */
const addSelectEvent = (cb) => {
  // region 框选事件
  let element = $('#content');
  let isMouseDown = false;
  let divSelection;
  let divSelectionInfo;
  element.on('mousedown', e => {
    let cellInfo = queryCellByDom(e.currentTarget);


    // 清空之前选择
    clearSelection(divSelection);

    isMouseDown = true;
    const rect = element[0].getBoundingClientRect();
    const __ret = addSelection(e, rect, divSelection, divSelectionInfo);
    divSelection = __ret.divSelection;
    divSelectionInfo = __ret.divSelectionInfo;
    console.log('mousedown')
    e.preventDefault()
  })
  element.on('mousemove', e => {
    if (isMouseDown) {
      requestAnimationFrame(() => {
        const rect = element[0].getBoundingClientRect();
        const offsetX = e.clientX - rect.left; // 视口坐标转元素相对坐标
        const offsetY = e.clientY - rect.top;
        // console.log(offsetX, offsetY);

        divSelectionInfo.left = (offsetX < divSelectionInfo.startX ? offsetX : divSelectionInfo.startX)
        divSelectionInfo.right = (offsetX < divSelectionInfo.startX ? divSelectionInfo.startX : offsetX)
        divSelectionInfo.top = (offsetY < divSelectionInfo.startY ? offsetY : divSelectionInfo.startY)
        divSelectionInfo.bottom = (offsetY < divSelectionInfo.startY ? divSelectionInfo.startY : offsetY)

        divSelection.css('left', divSelectionInfo.left + 'px')
        divSelection.css('top', divSelectionInfo.top + 'px')

        divSelectionInfo.width = Math.abs(offsetX - divSelectionInfo.startX)
        divSelectionInfo.height = Math.abs(offsetY - divSelectionInfo.startY)

        divSelection.css('width', divSelectionInfo.width + 'px')
        divSelection.css('height', divSelectionInfo.height + 'px')
      })
    }
    e.preventDefault()
  })
  element.on('mouseup', e => {
    if (isMouseDown) {
      // 重置鼠标状态
      $(document).css('cursor', '');
      isMouseDown = false;
      clearSelection(divSelection);
      cb && cb(divSelectionInfo)
      console.log('mouseup')
      e.preventDefault()
    }
  })
  element.on('mouseleave', e => {
    if (isMouseDown) {
      isMouseDown = false;
      clearSelection(divSelection);
      cb && cb(divSelectionInfo);
      console.log('mouseleave');
      e.preventDefault();
    }
  })
  // endregion
}


/**
 * 添加选中事件
 * @param cb
 */
const addRightClick = (cb) => {
  let element = $('#content');
  let isMouseDown = false;
  let divSelection;
  let divSelectionInfo;
  element.on('rightclick', e => {
    let cellInfo = queryCellByDom(e.currentTarget);


    // 清空之前选择
    clearSelection(divSelection);

    isMouseDown = true;
    const rect = element[0].getBoundingClientRect();
    const __ret = addSelection(e, rect, divSelection, divSelectionInfo);
    divSelection = __ret.divSelection;
    divSelectionInfo = __ret.divSelectionInfo;
    console.log('mousedown')
    e.preventDefault()
  })

}


/**
 * 添加单元格
 */
const addCell = () => {
  // 列容器
  for (let i = 1; i < colNum + 1; i++) {
    let div = document.createElement(`div`);
    div.id = `col_${i}`;
    div.setAttribute("class", "colCell");
    div.style.setProperty("width", GlobalValue.colWidth + 'px');
    div.style.setProperty("height", GlobalValue.rowHeight + 'px');
    div.innerText = numberToExcelColumn(i) + `(${i})`
    document.getElementById('col').appendChild(div)
    $(div).on('click', e => {
      let id = e.target.id;
      let colNum = id.split('_')[1] - 1
      console.log('选中整列', id, colNum)

      clearSelection()

      GlobalValue.colCellListSelected = {
        dom: e.target
      }
      // 获取选中的列
      // 添加选中的单元格
      GlobalValue.cellListSelected = GlobalValue.cellList.filter(x => x.col === colNum);
      GlobalValue.cellListSelected.forEach(x => {
        $(x.dom).css('border', GlobalValue.borderSelectionStyle);
      })

      $(div).css('border-top', GlobalValue.borderSelectionStyle)
      $(div).css('border-left', GlobalValue.borderSelectionStyle)
      $(div).css('border-right', GlobalValue.borderSelectionStyle)
    })
  }


  // 行容器
  for (var i = 1; i < rowNum + 1; i++) {
    let div = document.createElement(`div`);
    div.id = `col_${i}`;
    div.setAttribute("class", "rowCell")
    div.style.setProperty("width", GlobalValue.colWidth + 'px');
    div.style.setProperty("height", GlobalValue.rowHeight + 'px');

    div.innerText = i
    document.getElementById('row').appendChild(div)

    $(div).on('click', e => {
      let id = e.target.id;
      let rowNum = id.split('_')[1] - 1
      console.log('选中整行')

      clearSelection()

      GlobalValue.rowCellListSelected = {
        dom: e.target
      }
      // 获取选中的列
      // 添加选中的单元格
      GlobalValue.cellListSelected = GlobalValue.cellList.filter(x => x.row === rowNum);
      GlobalValue.cellListSelected.forEach(x => {
        $(x.dom).css('border', GlobalValue.borderSelectionStyle);
      })

      $(div).css('border-top', GlobalValue.borderSelectionStyle)
      $(div).css('border-left', GlobalValue.borderSelectionStyle)
      $(div).css('border-bottom', GlobalValue.borderSelectionStyle)
    })
  }


  // 单元格
  for (let i = 0; i < rowNum; i++) {

    for (let j = 0; j < colNum; j++) {
      // 创建带有内容和多个属性的div
      let div = document.createElement(`div`);
      div.id = `div_${i}_${j}`;

      let x = (GlobalValue.colWidth * j)
      let y = (GlobalValue.rowHeight * i)
      let width = GlobalValue.colWidth
      let height = GlobalValue.rowHeight

      div.style.setProperty('width', GlobalValue.colWidth + 'px');
      div.style.setProperty('height', GlobalValue.rowHeight + 'px');

      div.style.setProperty('left', x + 'px');
      div.style.setProperty('top', y + 'px');
      div.setAttribute('class', 'cell')

      $(div).on('click', e => {
        console.log("打印点击的div的id:", e.target.id)

        // let cellInfo = queryCellByDom(e.target);
        //
        //
        // if (lastCellClick && lastCellClick.dom) {
        //   lastCellClick.dom.style.setProperty('border', '1px solid #e6e6e6');
        // }

        // 删除上个input
        if (lastCellDblClick) {
          if (lastCellDblClick.input) {
            // 将input的值给dom
            lastCellDblClick.dom.innerText = lastCellDblClick.input.value;
            lastCellDblClick.input.remove();
          }
        }


        // e.target.style.setProperty('border', '2px solid green');
        // lastCellClick = cellInfo
        return true;
      })

      // 双击事件
      div.ondblclick = e => {
        console.log(e.target.id)

        // 找到对应的单元格
        let cellInfo = queryCellByDom(e.target);

        if (lastCellDblClick) {
          if (lastCellDblClick.input) {
            // 将input的值给dom
            lastCellDblClick.dom.innerText = lastCellDblClick.input.value;
            lastCellDblClick.input.remove();
          }
        }
        let input = document.createElement('input');
        input.setAttribute('class', 'cellInput');
        // 给输入框赋值
        input.value = cellInfo.value;
        // 删除dom中的值
        cellInfo.dom.innerText = ''
        // input的值变化
        input.onchange = e => {
          cellInfo.value = e.target.value;
          cellInfo.dom.innerText = e.target.value;
        }
        e.target.appendChild(input)
        input.focus()
        lastCellDblClick = cellInfo
        cellInfo.input = input
        return true;
      }

      GlobalValue.cellList.push(new Cell({
        row: i,
        col: j,
        dom: div,
        x, y,
        width, height,
        value: null,
        input: null,
      }))

      document.getElementById('content').appendChild(div)
    }

  }
}


onMounted(() => {
  (async () => {
    await DexieWrap.set('cellTemplate', [
      {row: 0, col: 0, value: '$name'},
      {row: 0, col: 1, value: '$age'},
    ])

    await DexieWrap.set('data', [
      {name: "666", age: "666"},
      {name: "777", age: "777"},
    ])

    let data = await DexieWrap.get('cellTemplate');


    let rows = []
    let cols = []

    // 添加cell
    addCell();


    GlobalValue.cellList.forEach(x => {
      data.forEach(y => {
        if (x.row === y.row && x.col === y.col) {
          x.value = y.value
          x.dom.innerText = y.value
        }
      })
    })

    addSelectEvent(info => {
      console.log("打印selection框信息:", info)

      GlobalValue.cellList.forEach(x => {

        // 如果是点击选中跳过
        let addX = 0.001;
        let addY = 0.001;
        if (info.left === info.right) {
          info.right += addX
        }
        if (info.top === info.bottom) {
          info.bottom += addY
        }

        // 框选区域, 必须闭环
        const polygon1 = turf.polygon([[
          [info.left, info.top], [info.right, info.top], [info.right, info.bottom], [info.left, info.bottom], [info.left, info.top]
        ]]);
        const polygon2 = turf.polygon([[
          [x.x, x.y], [x.x + x.width, x.y], [x.x + x.width, x.y + x.height], [x.x, x.y + x.height], [x.x, x.y]
        ]]);


        // 判断是否相交
        const intersection = turf.intersect(polygon1, polygon2);

        if (
            intersection !== null
        ) {
          // console.log(x)
          // $(x.dom).css('border', '2px solid green')
          GlobalValue.cellListSelected.push(x)
        }
      })

      // 如果有合并单元格, 对选中的单元格进行修正


      // 刷新框选样式
      // 上边框
      let rowMin = Math.min(...GlobalValue.cellListSelected.map(x => x.row))
      let rowMax = Math.max(...GlobalValue.cellListSelected.map(x => x.row + x.rowSpan - 1))
      let colMin = Math.min(...GlobalValue.cellListSelected.map(x => x.col))
      let colMax = Math.max(...GlobalValue.cellListSelected.map(x => x.col + x.colSpan - 1))


      GlobalValue.cellListSelected = GlobalValue.cellList
          .filter(x => x.row >= rowMin && x.row <= rowMax && x.col >= colMin && x.col <= colMax)

      // 获取指定行列范围内的所有单元格

      GlobalValue.cellListSelected
          .filter(x => x.dr === 0)
          .forEach(x => {
            if (rowMin === x.row) {
              $(x.dom).css('border-top', '2px solid green')
            }
            // 合并单元格的情况
            if (rowMax === x.row + x.rowSpan - 1) {
              $(x.dom).css('border-bottom', '2px solid green')
            }
            if (colMin === x.col) {
              $(x.dom).css('border-left', '2px solid green')
            }
            // 合并单元格的情况
            if (colMax === x.col + x.colSpan - 1) {
              $(x.dom).css('border-right', '2px solid green')
            }
          })
    })

  })()
})


/**
 * 合并单元格
 */
const merge = () => {
  console.log('合并单元格')
  if (GlobalValue.cellListSelected.length === 0) {
    return;
  }
  // 查看几行几列
  let rowCount = 1;
  let colCount = 1;
  let cellFirst = GlobalValue.cellListSelected[0];
  let rowFirst = GlobalValue.cellListSelected[0].row
  let colFirst = GlobalValue.cellListSelected[0].col
  GlobalValue.cellListSelected.slice(1).forEach(x => {
    rowCount = Math.max(rowCount, Math.abs(rowFirst - x.row) + 1)
    colCount = Math.max(colCount, Math.abs(colFirst - x.col) + 1)
  })

  console.log(`合并单元格:${rowCount}行${colCount}列`)

  cellFirst.rowSpan = rowCount;
  cellFirst.colSpan = colCount;
  cellFirst.width = colCount * GlobalValue.colWidth;
  cellFirst.height = rowCount * GlobalValue.rowHeight;
  $(cellFirst.dom).css('width', cellFirst.width + 'px')
  $(cellFirst.dom).css('height', cellFirst.height + 'px')

  GlobalValue.cellListSelected.slice(1).forEach(x => {
    $(x.dom).css("display", 'none');
    // $(x.dom).css("pointer-events", 'none');
    // 同时标记删除cellList中的数据
    x.dr = 1
  })

  // 清空边框样式
  GlobalValue.cellListSelected.forEach(x => {
    $(x.dom).css("border", 'none');
  })

  // 重新设置边框
  $(cellFirst.dom).css("border", '2px solid green');
}


</script>

<template>
  <div>
    <button @click="merge">合并单元格</button>
    <button @click="merge">取消单元格</button>
    <button @click="merge">整行删除</button>
    <button @click="merge">整列删除</button>
  </div>
  <div class="col-parent"
       :style="{height: GlobalValue.rowHeight + 'px',width:((rowNum+1)*GlobalValue.colWidth) + 'px'}">
    <div class="blank" :style="blankStyleObj"></div>
    <div id="col" class="col" :style="colContainerStyleObj"></div>
  </div>
  <div class="row-parent">
    <div id="row" class="row" :style="rowContainerStyleObj"></div>
    <div id="content" class="content"
         :style="{width:colContainerStyleObj.width, height:rowContainerStyleObj.height}"></div>
  </div>

</template>

<style lang="scss">

.col-parent {
  padding: 0;
  margin: 0;
  display: flex;
  //position: absolute;

  .blank {
    display: inline-block;
  }

  .col {
    display: flex;

    .colCell {
      border: 1px solid #e6e6e6;
      display: inline-block;
      box-sizing: border-box;
      text-align: center;
    }
  }
}

.row-parent {
  padding: 0;
  margin: 0;
  white-space: nowrap;
  display: flex;

  .row {
    display: flex;
    flex-direction: column;
    background: wheat;

    .rowCell {
      border: 1px solid #e6e6e6;
      display: inline-block;
      box-sizing: border-box;
      text-align: center;
    }
  }

  .content {
    width: 500px;
    display: inline-block;
    vertical-align: top;
    white-space: wrap;
    position: relative;


    .cell {
      border: 1px solid #e6e6e6;
      display: inline-block;
      box-sizing: border-box;
      position: absolute;

      .cellInput {
        height: 100%;
        width: 100%;
        outline: none;
        border: none;
        box-sizing: border-box;

      }
    }

    .divSelection {
      position: absolute;
      background: rgba(0, 0, 255, 0.5);
      pointer-events: none;
    }
  }
}


</style>
